﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using Sustainalytics.ClientDW.Entities;
using Sustainalytics.ClientDW.Entities.Universes;
using System;
using System.Collections.Generic;
using System.Linq;
using Moq;
using Sustainalytics.ClientDW.DataAccessLayer;

namespace Sustainalytics.Universes.Service.Tests
{
    [TestClass]
    public class CompanyUniversesSynchronizationTests
    {
        private List<Guid> _companyIds = new List<Guid>() { Guid.NewGuid(), Guid.NewGuid() };
        private List<UniverseCompany> _companyUniverses = null;
        private List<CorporateData> _corporateData = null;

        [TestInitialize]
        public void Initialize()
        {
            _companyUniverses = new List<UniverseCompany>();
            _corporateData = new List<CorporateData>();

            _companyUniverses.Add(new UniverseCompany() { Id = Guid.NewGuid(), CIQID = "IQ58912", CompanyId = _companyIds[0], Created = DateTime.UtcNow.AddDays(-5), LastUpdated = DateTime.UtcNow, UniverseId = 1 });
            _companyUniverses.Add(new UniverseCompany() { Id = Guid.NewGuid(), CIQID = "IQ58912", CompanyId = _companyIds[0], Created = DateTime.UtcNow.AddDays(-5), LastUpdated = DateTime.UtcNow, UniverseId = 2 });
            _companyUniverses.Add(new UniverseCompany() { Id = Guid.NewGuid(), CIQID = "IQ58912", CompanyId = _companyIds[0], Created = DateTime.UtcNow.AddDays(-5), LastUpdated = DateTime.UtcNow.AddDays(-5), UniverseId = 3 });
            _companyUniverses.Add(new UniverseCompany() { Id = Guid.NewGuid(), CIQID = "IQ58912", CompanyId = _companyIds[0], Created = DateTime.UtcNow.AddDays(-5), LastUpdated = DateTime.UtcNow, UniverseId = 4 });

            _companyUniverses.Add(new UniverseCompany() { Id = Guid.NewGuid(), CIQID = "IQ64571", CompanyId = _companyIds[1], Created = DateTime.UtcNow.AddDays(-5), LastUpdated = DateTime.UtcNow, UniverseId = 3 });
            _companyUniverses.Add(new UniverseCompany() { Id = Guid.NewGuid(), CIQID = "IQ64571", CompanyId = _companyIds[1], Created = DateTime.UtcNow.AddDays(-5), LastUpdated = DateTime.UtcNow.AddDays(-5), UniverseId = 2 });
            _companyUniverses.Add(new UniverseCompany() { Id = Guid.NewGuid(), CIQID = "IQ64571", CompanyId = _companyIds[1], Created = DateTime.UtcNow.AddDays(-5), LastUpdated = DateTime.UtcNow, UniverseId = 7 });
            _companyUniverses.Add(new UniverseCompany() { Id = Guid.NewGuid(), CIQID = "IQ64571", CompanyId = _companyIds[1], Created = DateTime.UtcNow.AddDays(-5), LastUpdated = DateTime.UtcNow, UniverseId = 8 });
            _companyUniverses.Add(new UniverseCompany() { Id = Guid.NewGuid(), CIQID = "IQ64571", CompanyId = _companyIds[1], Created = DateTime.UtcNow.AddDays(-5), LastUpdated = DateTime.UtcNow, UniverseId = 12 });

            _corporateData.Add(new CorporateData() { Id = _companyIds[0], CapitalIqId = 58912, CompanyName = "Company1", CompanyNameLowercase = "company1" });
            _corporateData.Add(new CorporateData() { Id = _companyIds[1], CapitalIqId = 64571, CompanyName = "Company2", CompanyNameLowercase = "company2" });
        }

        [TestMethod]
        public void SyncCompanyUniverses()
        {
            var universeRepository = new Mock<IUniversesRepository>();
            universeRepository.Setup(m => m.
                GetAllCompanyUniverses(It.IsAny<Guid>(), It.IsAny<DateTime>()))
                .Returns((Guid companyId, DateTime lastUpdate) =>
                {
                    return
                        _companyUniverses.Where(cu => cu.CompanyId == companyId && cu.LastUpdated > lastUpdate.Date)
                            .ToList();
                });

            var clientDwRepository = new Mock<IClientDwRepository>();
            clientDwRepository.Setup(m => m.GetCompanyIds()).Returns(() => _companyIds);

            Assert.IsNotNull(_corporateData.SingleOrDefault(cd => cd.Id == _companyIds[0]), "The corporate data for company 1 should not be null.");
            Assert.IsNotNull(_corporateData.SingleOrDefault(cd => cd.Id == _companyIds[1]), "The corporate data for company 2 should not be null.");
            Assert.AreEqual(3, _corporateData.SingleOrDefault(cd => cd.Id == _companyIds[0]).UniverseIds.Count, "The number of universes for company 1 is different than the expected one.");
            Assert.AreEqual(4, _corporateData.SingleOrDefault(cd => cd.Id == _companyIds[1]).UniverseIds.Count, "The number of universes for company 2 is different than the expected one.");
            Assert.IsFalse(_corporateData.SingleOrDefault(cd => cd.Id == _companyIds[0]).UniverseIds.Any(un => un == 3), "The universe with id 3 should not be found at company 1.");
            Assert.IsFalse(_corporateData.SingleOrDefault(cd => cd.Id == _companyIds[1]).UniverseIds.Any(un => un == 2), "The universe with id 2 should not be found at company 2.");
        }
    }
}
